package com.zhengx.blelib;

import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGattService;
import android.content.Context;
import android.os.Handler;
import android.util.Log;

import com.zhengx.blehelper.BleCallback;
import com.zhengx.blehelper.BleManager;
import com.zhengx.blehelper.BluetoothLeClient;

import java.util.List;
import java.util.UUID;

/**
 * Created by zx on 2018/4/20.
 */

public class LineRecordTask implements
        BleCallback.OnBleClientChangeListener,
        BleCallback.OnBluetoothStatusListener,
        BleCallback.OnScanStateChangedCallback{

    public static final String TAG = LineRecordTask.class.getSimpleName();

    private boolean isConnected = false;

    private String mac;

    private BleManager bleManager;

    private Handler overTimeHandler;

    private int writeReturnFlag = -1;

    private Context context;

    private LineRecordTask() {

    }

    private static class Singleton {
        private final static LineRecordTask instance = new LineRecordTask();
    }
    public static LineRecordTask getInstance(Context context) {
        if (Singleton.instance.context == null) {
            Singleton.instance.initCxt(context.getApplicationContext());
        }
        return Singleton.instance;
    }

    private void initCxt(Context context) {
        this.context = context;
        bleManager = BleManager.getInstance();
        overTimeHandler = new Handler();
        //blemanager 回调到LineRecordTask
        bleManager.setOnBluetoothStatusListener(this)
                .setDefaultCharacteristicsUUID(UUID.fromString("0000fff0-0000-1000-8000-00805f9b34fb"),
                        UUID.fromString("0000fff1-0000-1000-8000-00805f9b34fb"),
                        UUID.fromString("0000fff1-0000-1000-8000-00805f9b34fb"))
                .setScanTimeout(6 * 1000)
                .addOnBleClientChangeListener(this);


    }

    private Runnable writeOverTimeRunnable = new Runnable() {
        @Override
        public void run() {
            if (writeReturnFlag != -1) {
                if (onResponseCallback != null) {
                    onResponseCallback.onTimeOut();
                }
            }
            writeReturnFlag = -1;
        }
    };

    /**
     * 解析蓝牙数据
     * @param source
     */
    public void read(String mac, byte[] source) {
        Log.d(TAG, mac + " 接收蓝牙数据:" + source);
    }

    /**
     * 发送数据
     * @param code
     * @param cmd
     * @param callback
     */
    public void sendCommand(BluetoothLeClient client, int code, byte[] cmd, final OnResponseCallback callback) {
        Log.e(TAG, " send command: " + HexUtil.encodeHexStr(cmd));
        if (writeReturnFlag != -1) {
            return;
        }
        onResponseCallback = callback;
        if (client.isConnected()) {
            client.sendMsg(cmd);
            writeReturnFlag = code;
            overTimeHandler.postDelayed(writeOverTimeRunnable, 2000);
        } else {
            if (onResponseCallback != null) {
                onResponseCallback.onError("eof");
            }
        }
    }


    @Override
    public void onStatusChange(boolean isEnable) {
        if (isEnable) {
            Log.d(TAG, "蓝牙开启");
        } else {
            Log.d(TAG, "蓝牙关闭");
        }
    }

    @Override
    public void onConnected(BluetoothLeClient client) {
        isConnected = true;
        Log.d(TAG, "onconnect");
        this.mac = client.getClientMac();
    }

    @Override
    public void onConnectTimeout(BluetoothLeClient client) {
        Log.d(TAG, "连接蓝牙设备超时");
    }

    @Override
    public void onReConnect(BluetoothLeClient client, int count) {
        Log.d(TAG, "重连次数:" + count);
    }

    @Override
    public void onGattCharacteristicSet(BluetoothLeClient client) {
        Log.d(TAG, "connected service");
    }

    @Override
    public void onDisconnected(BluetoothLeClient client) {
        Log.d(TAG, "设备断开:" + client.getClientMac());
        isConnected = false;
        this.mac = "";
    }

    @Override
    public void onServiceDiscovered(BluetoothLeClient client, List<BluetoothGattService> services) {
        Log.d(TAG, "发现服务");
    }

    @Override
    public void onWriteValue(BluetoothLeClient client, byte[] writeHexStr) {
        Log.d(TAG, "on write:" + new String(writeHexStr));
    }

    @Override
    public void onRead(BluetoothLeClient client, BluetoothLeClient.MsgType msgType, byte[] source) {
//        Log.d(TAG, "onread：" + msgType);
        if (msgType == BluetoothLeClient.MsgType.NOTIFY) {
            read(client.getClientMac(), source);
        }
    }

    @Override
    public void onReadRemoteRssi(BluetoothLeClient client, int rssi, boolean success) {

    }

    @Override
    public void onStartScan() {
        Log.d(TAG, "扫描开始");
    }

    @Override
    public void onDiscoveryDevice(BluetoothDevice bluetoothDevice) {
        Log.d(TAG, "发现一个设备：" + bluetoothDevice.getAddress());
    }

    @Override
    public void onFindSpecifiedDevice(BluetoothDevice bluetoothDevice) {

    }

    @Override
    public void onFinished(boolean isCanceled, List<BluetoothDevice> devices) {
        Log.d(TAG, "canceled:" + isCanceled + "  " + devices);
        if (onConnectCallback != null) {
            onConnectCallback.foundDevices(devices);
        }
    }

    @Override
    public void onTimeOut() {

    }

    public BleManager getBleManager() {
        return bleManager;
    }

    public void setConnected(boolean connected) {
        isConnected = connected;
    }

    public void connectDevice(BluetoothDevice device) {

        getBleManager()
                .newBleClient(device)
//                .setNotifyMessageDecoder(new LineCustomMessageDecoder())
                .connect();
    }

    public void scanDevices() {
        getBleManager().scanDevices(this);
    }


    private OnConnectCallback onConnectCallback;

    public void setOnConnectCallback(OnConnectCallback onConnectCallback) {
        this.onConnectCallback = onConnectCallback;
    }

    public interface OnConnectCallback {
        void foundDevices(List<BluetoothDevice> bluetoothDevices);
    }

    /**
     * 写入返回回调
     */
    private OnResponseCallback onResponseCallback;

    public interface OnResponseCallback{
        void onSuccess(String str);
        void onError(String str);
        void onTimeOut();
    }
}
